package com.aoip.telemetry.telemetry.analysis.decode;

import com.aoip.telemetry.telemetry.core.analysis.decoder.Decoder;
import com.aoip.telemetry.telemetry.core.exception.MsgCodecException;
import com.aoip.telemetry.telemetry.core.redis.RedisCache;
import com.aoip.telemetry.telemetry.entity.common.OriginalMessageEntity;
import com.aoip.telemetry.telemetry.entity.common.OriginalMonitoringDataEntity;
import com.aoip.telemetry.telemetry.entity.common.TableDataEntity;
import com.aoip.telemetry.telemetry.entity.constant.TelemetryConstants;
import com.aoip.telemetry.telemetry.entity.element.ElementMessageEntity;
import com.aoip.telemetry.telemetry.entity.enums.CacheKeyEnum;
import com.aoip.telemetry.telemetry.entity.enums.MsgCodecStatusEnum;
import com.aoip.telemetry.telemetry.entity.enums.MsgTypeEnum;
import com.aoip.telemetry.telemetry.entity.sn.SnHydrologyEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 解析协议入口
 *
 * @author chenbai
 * @version 1.0
 * @date 2022/2/17 21:14
 */
@Component
@Slf4j
public class SnHydrologyMessageDecode implements Decoder {

    @Resource
    private SnHydrologyElementDataDecode elementDataDecode;
    @Resource
    private SnHydrologyElementDataSaveDb elementDataSaveDb;
    @Resource
    private RedisCache redisCache;
    @Override
    public Boolean ignoreMessages(String originalMessage) {
        String stCode = getStCode(originalMessage);
        if (!StringUtils.hasText(stCode)) {
            log.error("过滤报文，报文格式错误：{}", originalMessage);
            return true;
        }
        if (unregisteredStCode(stCode)) {
            log.error("过滤报文，站点未注册：{}", originalMessage);
            return true;
        }
        if (originalMessage.length() < 10) {
            log.error("过滤报文，报文长度不够：{}", originalMessage);
            return true;
        }
        return false;
    }

    @Override
    public OriginalMessageEntity originalMsgFrame(String originalMessage) {
        SnHydrologyEntity entity = SnHydrologyFrameDecode.decode(originalMessage);
        String stCode = entity.getStCode();
        entity.setStCode(stCode);
        OriginalMessageEntity originalMsg = new OriginalMessageEntity();
        String elementData = entity.getElementData();
        originalMsg.setMsgBody(elementData);
        originalMsg.setMsgText(originalMessage);
        originalMsg.setMsgType(MsgTypeEnum.HYDROLOGY.getCode());
        originalMsg.setMsgStatus(MsgCodecStatusEnum.MSG_CORRECT.getCode());
        originalMsg.setStCode(stCode);
        int length = stCode.length();
        if (length >= 2) {
            originalMsg.setFunctionCode(stCode.substring(length - 2, length));
        } else {
            originalMsg.setFunctionCode(stCode);
        }
        return originalMsg;
    }

    @Override
    public OriginalMessageEntity entry(OriginalMessageEntity originalMsg) {
        SnHydrologyEntity entity = new SnHydrologyEntity();
        String stCode = originalMsg.getStCode();
        int length = stCode.length();
        String stCd = stCode.substring(0, length - 2);
        entity.setStCode(stCd);
        String msgText = originalMsg.getMsgText();
        entity.setAllMsg(msgText);
        String msgBody = originalMsg.getMsgBody();
        entity.setElementData(msgBody);
        if (stCd.endsWith("11111111")) {
            log.error("originalMsg:{}" , originalMsg);
        }
        if (msgText.contains(TelemetryConstants.ER)) {
            throw new MsgCodecException(MsgCodecStatusEnum.MSG_ER);
        }
        Map<String, Object> dataMap = elementDataDecode.elementDataDecode(msgBody, originalMsg, entity);
        List<ElementMessageEntity> elementMessageEntityList = (List<ElementMessageEntity>) dataMap.get("elementList");
        List<OriginalMonitoringDataEntity> monitoringDataEntityList = (List<OriginalMonitoringDataEntity>) dataMap.get("monitoringDataEntityList");
        if (elementMessageEntityList == null || elementMessageEntityList.size() < 1) {
            throw new MsgCodecException(MsgCodecStatusEnum.NON_MONITOR_DATA);
        } else {
            List<TableDataEntity> list = elementDataSaveDb.saveElementData(elementMessageEntityList, entity);
            originalMsg.setTableDataEntityList(list);
        }
        originalMsg.setMonitoringDataList(monitoringDataEntityList);
        return originalMsg;
    }

    private String getStCode(String originalMessage) {
        int st = originalMessage.indexOf("ST");
        int stCodeBeginIndex = st + 3;
        int stCodeEndIndex = originalMessage.indexOf(" " , 3);
        return originalMessage.substring(stCodeBeginIndex, stCodeEndIndex);
    }

    /**
     * 未注册的测站，不存在，返回true，存在返回false
     * @author chenbai
     * @date 2022/11/25
     * @param stCode 测站编码
     * @return java.lang.Boolean
     **/
    private boolean unregisteredStCode(String stCode){
        Collection<String> keys = redisCache.keys(CacheKeyEnum.STATION + ":*" + stCode);
        return keys == null || keys.size() < 1;
    }

}
